問題描述
如何在沒有全局變量的情況下一直保留我的變量? (How can I keep my variable all the time without global variables?)
I have two GridViews. I've got method GetGeneralDiagnosis
which returns a list of all diagnosis:
CODE DIAGNOSIS F50 Eating disorders F51 Nonorganic sleep disorders
and method GetSpecificDiagnosis
which returns more specific list:
CODE DIAGNOSIS F50.0 Anorexia nervosa F50.1 Atypical anorexia nervosa F51.0 Nonorganic insomnia F51.1 Nonorganic hypersomnia
Now I've got method which bind SPECIFIC DIAGNOSIS to second GridView according to GENERAL DIAGNOSIS from first GridView.
protected void gvGeneralDiagnosis_SelectedIndexChanged(object sender, EventArgs e)
{
string generalDiagnosis = gvGeneralDiagnosis.DataKeys[gvGeneralDiagnosis.SelectedIndex].Values["ICD10Code"].ToString();
var ICD10 = Visit.GetSpecificDiagnosis(); // here I'm getting data from database
gvSpecificDiagnosis.DataSource = ICD10.Where(i => i.ICD10Code.Contains(generalDiagnosis)).Select(i => new { i.ICD10Name, i.ICD10Code });
gvSpecificDiagnosis.DataBind();
}
I don't want to connect to database each time selected index is changed.
How can i get my list var ICD10 = Visit.GetSpecificDiagnosis()
only once? I heard that global variables are very bad idea, so how can I do that in another way?
‑‑‑‑‑
參考解法
方法 1:
You can have your Visit
class cache the returned data.
When GetSpecificDiagnosis
is called, it will check whether this data was already retrieved from the database, and return it if it was. If it wasn't, it'll retrieve it from the database and save it to its cache.
One thing you should pay attention to is whether this data is static (i.e. never changes throughout the application's lifetime) or is it dynamic. In the first case, you won't have to do any special handling, but if it's the latter, you'll have to invalidate the cache one the information in the database has changed.
I recommend you to have a look here to see how to get started with caching in ASP.NET.
方法 2:
You can use a private member variable. This one "lives" as long as the class containing it lives. Wrap it with a property to access it and automatically read it from the database, if necessary.
private TypeOfICD10 _icd10;
private TypeOfICD10 ICD10
{
get
{
if (_icd10 == null) { // Get from database.
_icd10 = Visit.GetSpecificDiagnosis();
}
return _icd10;
}
}
Now you can use it like this and it will be read from the db only at the first call
protected void gvGeneralDiagnosis_SelectedIndexChanged(object sender, EventArgs e)
{
string generalDiagnosis = gvGeneralDiagnosis.DataKeys[gvGeneralDiagnosis.SelectedIndex].Values["ICD10Name"].ToString();
gvSpecificDiagnosis.DataSource = ICD10
.Where(i => i.ICD10Code.Contains(generalDiagnosis))
.Select(i => new { i.ICD10Name, i.ICD10Code });
gvSpecificDiagnosis.DataBind();
}
方法 3:
I don't know much about the Visist class from your question but why not cache ICD10 this way you will be using the cached object and the Database call will made only if the Cache Key ICD10 has a value of null
Example :
if(Cache["ICD10"] == null)
{
var ICD10 = Visit.GetSpecificDiagnosis();
Cache["ICD10"] = ICD10;
}
else
{
var ICD10 = Cache["ICD10"];
}
(by vanilla161、Adi Lester、Olivier Jacot‑Descombes、HatSoft)